﻿using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml.Serialization;

namespace ClientSocket
{
    /// <summary>
    ///SOCKET客户端
    /// </summary>
    public class ClientSocket
    {
        private Socket socketSend;
        private bool beginSign;
        private Thread threadReceive;
        private string ip;
        private int port;
        private IClientSocket clientSocket;
        private byte[] buffer;
        private ClientModel clientModel;
        private DateTime writeDateTime, readDateTime;
        private bool retry;
        private int retryTime;
        private string token;
        private bool enableHeart;
        private int heartDelaySecond = 10;
        private System.Threading.Timer heartTimer;
        /// <summary>
        /// 心跳间隔时间，默认10秒
        /// </summary>
        private const int heartInterval = 10;

        /// <summary>
        /// Socket客户端类
        /// </summary>
        /// <param name="Ip">服务端IP</param>
        /// <param name="Port">服务端PORT</param>
        /// <param name="BufferSize">接收消息缓冲区大小，默认1024字节</param>
        /// <param name="RetryTime">重连时间，默认5秒</param>
        /// <param name="clientSocket">回调实体类</param>
        public ClientSocket(int BufferSize, int RetryTime)
        {
            Ini(BufferSize, true, RetryTime);
        }
        /// <summary>
        /// Socket客户端类
        /// </summary>
        /// <param name="Ip">服务端IP</param>
        /// <param name="Port">服务端PORT</param>
        /// <param name="clientSocket">回调实体类</param>
        public ClientSocket()
        {
            Ini(1024, true, 5);
        }

        /// <summary>
        /// Socket客户端类
        /// </summary>
        /// <param name="Ip">服务端IP</param>
        /// <param name="Port">服务端PORT</param>
        /// <param name="RetryTime">重连时间，默认5秒</param>
        /// <param name="clientSocket">回调实体类</param>
        public ClientSocket(int RetryTime)
        {
            Ini(1024, true, RetryTime);
        }

        private void Ini(int bufferSize, bool retry, int retryTime)
        {
            if (retry && retryTime < 1)
                retryTime = 1;
            if (bufferSize < 256)
                bufferSize = 256;
            this.enableHeart = false;
            this.buffer = new byte[bufferSize];
            this.retry = retry;
            this.retryTime = retryTime;
            this.writeDateTime = this.readDateTime = DateTime.Now;
            clientModel = new ClientModel();
        }
        public bool StartHeart()
        {
            if (beginSign)
            {
                this.enableHeart = true;
                heartTimer = new Timer(new TimerCallback(HeartTimeCallBack), enableHeart, 0, 1000);
                heartTimer.Change(1, 1000);
            }
            return beginSign;
        }

        public bool StopHeart()
        {
            if (beginSign)
            {
                this.enableHeart = false;
                if (heartTimer != null)
                {
                    heartTimer.Change(-1, 1000);
                }
            }
            return beginSign;
        }
        private void HeartTimeCallBack(object state)
        {
            if (bool.Parse(state.ToString()))
            {
                //发出心跳
                DateTime date = DateTime.Now;
                if (DateTime.Compare(date, this.writeDateTime.AddSeconds(heartDelaySecond - 1)) > 0)
                {
                    if (this.WriteHeart())
                        clientSocket.SocketHeart(date);
                }
            }

        }
        private bool GetWebIdentity(string token)
        {
            return token != null && token.Length > 0;
        }
        public void SetStopBefore()
        {
            this.beginSign = false;
        }
        /// <summary>
        /// 启动SOCEKT
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="clientSocket"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool Start(string ip, int port, IClientSocket clientSocket, string token, UseTypeEnum useTypeEnum)
        {
            beginSign = false;
            try
            {
                if (GetWebIdentity(token))
                {
                    this.ip = ip;
                    this.port = port;
                    this.clientSocket = clientSocket;
                    this.token = token;
                    socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socketSend.Connect(IPAddress.Parse(this.ip), this.port);
                    clientSocket.SocketConnectorSuccess(this.ip, this.port);

                    Thread.Sleep(200);
                    string TaskId = null;

                    if (WriteIdentityMessage(out TaskId, useTypeEnum, token))
                    {
                        //线程接收服务器发送消息
                        beginSign = true;
                        threadReceive = new Thread(new ThreadStart(Receive));
                        threadReceive.IsBackground = true;
                        threadReceive.Start();
                    }
                    if (!beginSign)
                    {
                        clientSocket.SocketIdentityError(string.Format("Token：[{0}]不合法", token));
                        socketSend.Close();
                        clientSocket.SocketConnectorClose();
                    }
                }
                else
                {
                    clientSocket.SocketIdentityError(string.Format("Token：[{0}]不合法", token));
                }

                return beginSign;
            }
            catch (Exception exception)
            {
                beginSign = false;
                clientSocket.SocketError(exception.Message);
                return beginSign;
            }
        }

        /// <summary>
        /// 我要下线
        /// </summary>
        /// <param name="taskId"></param>
        /// <returns></returns>
        public bool WriteExit(out string taskId)
        {
            taskId = null;
            return WriteMessage(null, out taskId, FunctionEnum.EXIT_CONNECT, OperatorEnum.EQUALTO, UseTypeEnum.TEN);
        }
        /// <summary>
        /// 注册身份
        /// </summary>
        /// <param name="Content"></param>
        /// <param name="taskId"></param>
        /// <param name="userTypeCode"></param>
        /// <returns></returns>
        public bool WriteIdentityMessage(out string taskId, UseTypeEnum userTypeCode, string token)
        {
            taskId = null;
            if ((byte)userTypeCode > 2)
            {
                return WriteMessage(token
                    , out taskId
                    , FunctionEnum.CHECK_IDENTITY
                    , OperatorEnum.EQUALTO
                    , userTypeCode);
            }
            else
            {
                taskId = string.Format("身份类型数值不能小于{0}", 2);
                return false;
            }

        }

        public bool WriteMessage(string content, out string taskId, FunctionEnum functionEnum, OperatorEnum operatorEnum, UseTypeEnum userTypeCode)
        {
            if (functionEnum != FunctionEnum.SEND_HEART)
                taskId = clientModel.GetTaskId();
            if (content != null)
                clientModel.SetContent(content);
            byte[] buffer = clientModel.GetMessageByte(functionEnum
                , operatorEnum
                , userTypeCode
                , out taskId);
            if (buffer != null && buffer.Length > 0)
            {
                //if (functionEnum == FunctionEnum.CHECK_IDENTITY)
                //{
                   // ClientTool.WriteTxt("c:\\", "identity", buffer);
                //}
                if (socketSend.Send(buffer) > 0)
                {
                    this.writeDateTime = DateTime.Now;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
                return false;
        }
        public bool WriteHeart()
        {
            if (socketSend.Send(clientModel.GetHeart()) > 0)
            {
                this.writeDateTime = DateTime.Now;
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="content"></param>
        /// <param name="taskId"></param>
        /// <returns></returns>
        public bool WriteMessage(string content, out string taskId, OperatorEnum operatorEnum, UseTypeEnum useTypeEnum)
        {
            taskId = null;
            return WriteMessage(content, out taskId, FunctionEnum.SEND_MESSAGE, operatorEnum, useTypeEnum);
        }

        /// <summary>
        /// 接口服务器发送的消息
        /// </summary>
        private void Receive()
        {
            try
            {
                while (beginSign)
                {
                    int Length = socketSend.Receive(buffer);
                    if (beginSign && Length > 0)
                    {
                        byte[] array = new byte[Length];
                        Array.Copy(buffer, 0, array, 0, Length);
                        this.readDateTime = DateTime.Now;
                        clientSocket.SocketReceiveMessage(array);
                    }
                }
            }
            catch (Exception exception)
            {
                clientSocket.SocketError(exception.Message);
            }
        }

        public void Close()
        {
            StopHeart();
            if (socketSend.Connected)
            {
                socketSend.Close();
                socketSend.Dispose();
            }
            clientSocket.SocketConnectorClose();
        }
        public void SetBeginSign(bool beginSign)
        {
            this.beginSign = beginSign;
        }

        public bool GetBeginSign()
        {
            return this.beginSign;
        }
    }
    /// <summary>
    /// 功能码枚举
    /// </summary>
    public enum FunctionEnum : byte
    {
        /// <summary>
        /// 未知功能
        /// </summary>
        UNKOWN = 0x50,
        /// <summary>
        /// 反馈应答校验位出错
        /// </summary>
        RETURN_ERROR = 0x51,
        /// <summary>
        /// 反馈应答正常
        /// </summary>
        RETURN_OK = 0x52,
        /// <summary>
        /// 注册身份
        /// </summary>
        CHECK_IDENTITY = 0x30,
        /// <summary>
        /// 发出心跳
        /// </summary>
        SEND_HEART = 0x31,
        /// <summary>
        /// 我要断开连接
        /// </summary>
        EXIT_CONNECT = 0x32,
        /// <summary>
        /// 发出业务消息
        /// </summary>
        SEND_MESSAGE = 0x33,
        /// <summary>
        /// 我要入群
        /// </summary>
        INTO_GROUP = 0x34,
        /// <summary>
        /// 我要出群
        /// </summary>
        OUT_GROUP = 0x35
    }
    /// <summary>
    /// 转发码枚举
    /// </summary>
    public enum OperatorEnum : byte
    {
        /// <summary>
        /// 除自己之外，全部转发
        /// </summary>
        NO_FORWARD = 0x30,
        /// <summary>
        /// 小于
        /// </summary>
        LESSTHAN = 0x31,
        /// <summary>
        /// 小于等于
        /// </summary>
        LESSTHAN_EQUALTO = 0x32,
        /// <summary>
        /// 等于
        /// </summary>
        EQUALTO = 0x33,
        /// <summary>
        /// 大于等于
        /// </summary>
        BIGIN_EQUALTO = 0x34,
        /// <summary>
        /// 大于
        /// </summary>
        BIGIN = 0x35,
        /// <summary>
        /// 指定
        /// </summary>
        TO = 0x36,
        /// <summary>
        /// 转成所有
        /// </summary>
        ALL = 0x37
    }
    /// <summary>
    /// 用户类型
    /// </summary>
    public enum UseTypeEnum : byte
    {
        TEN = 0x3A,
        ELEVEN = 0x3B,
        TWELVE = 0x3C,
        THIRTEEN = 0x3D,
        FOURTEEN = 0x3E,
        FIFTEEN = 0x3F,
        SIXTEEN = 0x40,
        SEVENTEEN = 0x41,
        EIGHTEEN = 0x42,
        NINETEEN = 0x43,
        TWENTY = 0x44
    }
    /// <summary>
    /// 序列化类
    /// </summary>
    public class XmlUtil
    {
        /// <summary>
        /// 序列化到XML
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="directory"></param>
        /// <param name="fileName"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool ObjectSerialXml<T>(string directory, string fileName, T t)
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(directory);
            if (!directoryInfo.Exists)
                directoryInfo.Create();

            try
            {
                using (FileStream fs = new FileStream(string.Format("{0}\\{1}.xml", directory, fileName), FileMode.Create))
                {

                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    serializer.Serialize(fs, t);

                    fs.Dispose();

                    return true;
                }

            }
            catch (Exception e)
            {

                throw e;
            }
        }

        /// <summary>
        /// 从xml序列中反序列化
        /// </summary>
        /// <param name="XmlFile"></param>
        /// <returns></returns>
        public static T XmlSerialObject<T>(string fileFullName) where T : class
        {

            if (!System.IO.File.Exists(fileFullName))
                throw new Exception("文件不存在");

            T t = null;
            try
            {
                //Xml格式反序列化
                using (Stream stream = new FileStream(fileFullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    XmlSerializer formatter = new XmlSerializer(typeof(T));
                    t = (T)formatter.Deserialize(stream);
                    stream.Dispose();
                }

                return t;
            }
            catch (Exception e)
            {

                throw e;
            }
        }
    }

    /// <summary>
    /// 工具类
    /// </summary>
    public class ClientTool
    {
        #region 正则表达式
        private const string MatchContent = @"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";
        private const string Url = @"((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?";
        private const string Email = @"(\w+\.) * \w+@(\w+\.)+[A-Za-z]+";
        private const string Domain = @"^([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?$";
        //private const string Domain = @"^(http://|https://)([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?$";
        #endregion

        public static bool MatchDomain(string domain)
        {
            return _Match(domain, Domain);
        }
        public static bool MatchEmail(string email)
        {
            return _Match(email, Email);
        }
        public static bool MatchUrl(string url)
        {
            return _Match(url, Url);
        }
        public static bool MatchIpAddress(string ipAddress)
        {
            return _Match(ipAddress, MatchContent);
        }

        /// <summary>
        /// 正则表达式判断
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="MatchContent">正则表达式</param>
        /// <returns>是否OK</returns>
        private static bool _Match(string content, string MatchContent)
        {
            if (content == null)
                return false;
            Regex regex = new Regex(MatchContent);
            return regex.IsMatch(content);
        }
        public static string WriteTxt(string Path, string FileName, byte[] vs)
        {
            if (vs == null || vs.Length == 0)
                return null;
            if (!Directory.Exists(Path))
                Directory.CreateDirectory(Path);
            FileName = string.Format("{0}\\{1}.txt", Path, FileName);
            using (FileStream fileStream = new FileStream(FileName, FileMode.OpenOrCreate))
            {
                fileStream.Write(vs, 0, vs.Length);
                fileStream.Flush();
                fileStream.Close();
                fileStream.Dispose();
            }
            return FileName;
        }
        public static byte[] GetMessageByte(byte funcCode
            , byte operateCode
            , byte useType
            , bool oddSign
            , string TaskId
            , string Content
            , byte BeginSite)
        {
            byte[] ContentByte = null;
            int Length = 9;
            if (Content != null)
            {
                ContentByte = Encoding.UTF8.GetBytes(TaskId + Content);
                Length += ContentByte.Length;
            }
            byte[] array = new byte[Length];
            int index = 0;
            array[index++] = BeginSite;
            array[index++] = (byte)(Length & 0xff);// 最低位
            array[index++] = (byte)((Length >> 8) & 0xff);// 次低位
            array[index++] = (byte)((Length >> 16) & 0xff);// 次高位
            array[index++] = (byte)((Length >> 24) & 0xff);// 最高位,无符号右移。
            array[index++] = funcCode;//加入功能码
            array[index++] = operateCode;//加入转发码
            array[index++] = useType;//加入转发用户类型
            if (ContentByte != null)
            {
                Array.Copy(ContentByte, 0, array, index, ContentByte.Length);//COPY消息内容到报文体
                index += ContentByte.Length;
            }
            array[index] = oddSign ? getOddSite(array) : getEvenSite(array);
            return array;
        }
        /// <summary>
        /// 得到功能码
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static byte getFunctionCode(byte[] array)
        {
            return array[5];
        }
        /// <summary>
        /// 得到操作码
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static byte getOperateCode(byte[] array)
        {
            return array[6];
        }

        private static byte getMessageCode(byte[] array, int index)
        {
            if (index > array.Length - 1 && index < 0)
            {
                return 0;
            }
            else
            {
                return array[index];
            }
        }
        private static int getOneCount(byte[] array)
        {
            int count = 0;
            for (int i = 0; i < array.Length; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if ((array[i] >> j & 0x01) == 1)
                        count++;
                }
            }
            return count;
        }

        public static bool checkOdd(byte[] array)
        {
            return checkSite(array, true);
        }

        private static bool checkSite(byte[] array, bool oddSign)
        {
            int length = array.Length;
            byte[] checkArray = new byte[length - 1];
            Array.Copy(array, 0, checkArray, 0, length - 1);
            int count = getOneCount(checkArray);
            if (count % 2 == 0)
            {
                if (oddSign)
                {
                    return array[length - 1] == (byte)0x01;
                }
                else
                {
                    return array[length - 1] == (byte)0x00;
                }
            }
            else
            {
                if (oddSign)
                {
                    return array[length - 1] == (byte)0x00;
                }
                else
                {
                    return array[length - 1] == (byte)0x01;
                }
            }
        }

        public static int bytes2Int(byte[] bytes)
        {
            int int1 = bytes[0] & 0xff;
            int int2 = (bytes[1] & 0xff) << 8;
            int int3 = (bytes[2] & 0xff) << 16;
            int int4 = (bytes[3] & 0xff) << 24;

            return int1 | int2 | int3 | int4;
        }

        private static byte getOddSite(byte[] array)
        {
            return getCheckByte(array, true);
        }

        private static byte getEvenSite(byte[] array)
        {
            return getCheckByte(array, false);
        }

        private static byte getCheckByte(byte[] array, bool oddSign)
        {
            int count = getOneCount(array);
            if (count % 2 == 0)
            {
                return oddSign ? (byte)0x01 : (byte)0x00;
            }
            else
            {
                return oddSign ? (byte)0x00 : (byte)0x01;
            }
        }

        public static ClientModel GetClientMessage(byte[] array, out string returnMessage)
        {
            if (array == null || array.Length == 0)
            {
                returnMessage = "数组为空";
                return null;

            }
            if (array[0] != 0x02)
            {
                returnMessage = "开始符不合法";
                return null;
            }
            if (checkOdd(array))
            {
                byte[] lengthArray = new byte[4];
                Array.Copy(array, 1, lengthArray, 0, 4);
                int Length = bytes2Int(lengthArray);
                ClientModel clientModel = new ClientModel(false);
                clientModel.SetFunctionCode(array[5]);
                clientModel.SetOperateCode(array[6]);
                clientModel.SetUserType(array[7]);
                if (Length > 9)
                {
                    byte[] ContentArray = new byte[Length - 9];
                    Array.Copy(array, 8, ContentArray, 0, ContentArray.Length);
                    string Content = Encoding.UTF8.GetString(ContentArray, 0, ContentArray.Length);
                    clientModel.SetTaskId(Content.Substring(0, 5).Trim());
                    clientModel.SetContent(Content.Substring(5, Content.Length - 5));
                }
                returnMessage = "正确解析";
                return clientModel;
            }
            else
            {
                returnMessage = "校验出错";
                return null;
            }
        }

    }
    /// <summary>
    /// 报文类
    /// </summary>
    public class ClientModel
    {
        /// <summary>
        /// 功能码
        /// </summary>
        private byte funcCode;
        /// <summary>
        /// 转发码
        /// </summary>
        private byte operCode;
        /// <summary>
        /// 用户类型码
        /// </summary>
        private byte userType;
        /// <summary>
        /// 任务ID
        /// </summary>
        private string TaskId;
        /// <summary>
        /// 报文内容
        /// </summary>
        private string Content;
        /// <summary>
        /// 是否自动生成TaskId
        /// </summary>
        private bool AutoTaskId;
        /// <summary>
        /// 报文开始符
        /// </summary>
        private byte BeginSite = 0x02;
        /// <summary>
        /// TaskId规定长度，为5
        /// </summary>
        private int TaskIdLength = 5;
        private Random random = new Random(1);

        private string AddNo(string TaskId, int Length)
        {
            if (TaskId != null)
                TaskId = TaskId.Trim();

            if (TaskId.Length > Length)
            {
                return TaskId.Substring(0, Length);
            }
            else
            {
                int Count = Length - TaskId.Length;
                int index = 0;
                while (index < Count)
                {
                    TaskId += " ";
                    index++;
                }
                return TaskId;
            }
        }

        public ClientModel()
        {
            AutoTaskId = true;
        }

        public ClientModel(bool autoTaskId)
        {
            AutoTaskId = autoTaskId;
        }

        public byte GetFunctionCode()
        {
            return this.funcCode;
        }

        public byte GetOperateCode()
        {
            return this.operCode;
        }

        public byte GetUseType()
        {
            return this.userType;
        }

        public void SetFunctionCode(byte funcCode)
        {
            this.funcCode = funcCode;
        }

        public void SetOperateCode(byte operCode)
        {
            this.operCode = operCode;
        }

        public void SetUserType(byte userType)
        {
            this.userType = userType;
        }
        public string GetTaskId()
        {
            if (AutoTaskId)
            {
                int RandNum = random.Next(0, 100000);
                return AddNo(RandNum.ToString(), TaskIdLength);
            }
            else
                return this.TaskId;
        }

        public void SetTaskId(string TaskId)
        {
            if (!AutoTaskId)
                this.TaskId = AddNo(TaskId, TaskIdLength);
        }

        public string GetContent()
        {
            return this.Content;
        }

        public void SetContent(string Content)
        {
            this.Content = Content;
        }

        public string GetMessage()
        {
            return string.Format("{0}{1}"
                , GetTaskId()
                , GetContent());
        }

        public byte[] GetMessage(OperatorEnum operatorEnum
            , UseTypeEnum userTypeCode
            , out string TaskId)
        {
            return GetMessageByte(FunctionEnum.SEND_MESSAGE
                , operatorEnum
                , userTypeCode
                , out TaskId);
        }

        public byte[] GetHeart()
        {
            int index = 0;
            byte[] buffer = new byte[9];
            buffer[index++] = this.BeginSite;

            buffer[index++] = 0x09;
            buffer[index++] = 0x00;
            buffer[index++] = 0x00;
            buffer[index++] = 0x00;

            buffer[index++] = (byte)FunctionEnum.SEND_HEART;
            buffer[index++] = (byte)OperatorEnum.NO_FORWARD;
            buffer[index++] = (byte)UseTypeEnum.TEN;
            buffer[index++] = 0x01;
            return buffer;
        }

        public byte[] GetMessageByte(FunctionEnum functionEnum
            , OperatorEnum operatorEnum
            , UseTypeEnum userTypeCode
            , out string TaskId)
        {
            int ContentLength = 9;
            if (functionEnum != FunctionEnum.SEND_HEART)
            {
                TaskId = this.GetTaskId();
                ContentLength += 5;
            }
            else
            {
                TaskId = null;
                Content = null;
            }
            if (Content != null)
            {
                ContentLength += Encoding.UTF8.GetBytes(Content).Length;
            }

            if (ContentLength > 1024)
            {
                TaskId = string.Format("任务ID与内容总长度不允许超过{0}字节", 1015);
                return null;
            }

            if (ContentLength % 256 == 2 || ContentLength / 256 == 2)
            {
                TaskId = string.Format("任务ID与内容总长度除以256后，商数、余数都不能是{0}", 2);
                return null;
            }
            return ClientTool.GetMessageByte((byte)functionEnum
                , (byte)operatorEnum
                , (byte)userTypeCode
                , true, TaskId, Content, this.BeginSite);
        }

        //public byte[] GetIntoGroup(string groupId, out string TaskId)
        //{
        //    return _GetGroup(groupId, true, out TaskId);
        //}

        //public byte[] GetOutGroup(string groupId, out string TaskId)
        //{
        //    return _GetGroup(groupId, false, out TaskId);
        //}

        //private byte[] _GetGroup(string groupId, bool isInto, out string TaskId)
        //{
        //    this.Content = groupId;
        //    FunctionEnum functionEnum = isInto ? FunctionEnum.INTO_GROUP : FunctionEnum.OUT_GROUP;
        //    return GetMessageByte(functionEnum, OperatorEnum.EQUALTO, UseTypeEnum.TEN, out TaskId);
        //}
    }
    /// <summary>
    /// Socket客户端接口
    /// </summary>
    public interface IClientSocket
    {
        void SocketIdentityError(string ErrorMessage);
        /// <summary>
        /// 连接断开事件
        /// </summary>
        void SocketConnectorClose();
        /// <summary>
        /// 连接成本事件
        /// </summary>
        /// <param name="Ip">服务端IP</param>
        /// <param name="Port">服务端PORT</param>
        void SocketConnectorSuccess(string Ip, int Port);
        /// <summary>
        /// 接收消息事件
        /// </summary>
        /// <param name="array"></param>
        void SocketReceiveMessage(byte[] array);
        /// <summary>
        /// 错误事件
        /// </summary>
        /// <param name="Error"></param>
        void SocketError(string Error);
        /// <summary>
        /// 心跳发出
        /// </summary>
        /// <param name="HeartDateTime"></param>
        void SocketHeart(DateTime LastHeartSendTime);
    }

    public class WriteModel
    {
        public string Path;
        public DateTime dateTime;
        public byte[] array;
    }
}
